package auth

import (
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt"
	"ruoyi/config"
	"ruoyi/domain/entity/request"
	"ruoyi/domain/entity/response"
	"ruoyi/domain/entity/system"
	"strings"
)

type Jwt struct{}

func NewJwtToken() *Jwt {
	return &Jwt{}
}

type JwtInterface interface {
	CreateToken(system.SysUser) (string, error)
	VerifyToken(tokenStr string) (*jwt.Token, error)
	JWTAuthMiddleware() func(ctx *gin.Context)
}

// Token implements the TokenInterface
var _ JwtInterface = &Jwt{}

func (j *Jwt) CreateToken(user system.SysUser) (string, error) {
	claims := request.LoginUser{UserId: user.UserId, DeptId: user.DeptId}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, &claims)
	mySigningKey := []byte(config.Jwt.Secret)
	return token.SignedString(mySigningKey)
}

func (j *Jwt) VerifyToken(tokenStr string) (*jwt.Token, error) {
	mySigningKey := []byte(config.Jwt.Secret)
	tokenStr = strings.ReplaceAll(tokenStr, config.HeaderSignTokenStr, "")
	return jwt.Parse(tokenStr, func(t *jwt.Token) (interface{}, error) {
		return mySigningKey, nil
	})
}

func (j *Jwt) JWTAuthMiddleware() func(ctx *gin.Context) {
	return func(ctx *gin.Context) {
		// 根据实际情况取TOKEN, 这里从request header取
		header := ctx.Request.Header
		tokenStr := header.Get(config.HeaderSignToken)
		if len(tokenStr) < 1 {
			response.FailWithMessage("参数错误", ctx)
			return
		}

		token, err := j.VerifyToken(tokenStr) // 调用j.VerifyToken
		if err != nil {
			response.FailWithMessage("认证失败", ctx)
			return
		}
		userId := token.Claims.(jwt.MapClaims)["userId"]
		deptId := token.Claims.(jwt.MapClaims)["deptId"]
		// 此处已经通过了, 可以把Claims中的有效信息拿出来放入上下文使用
		ctx.Set("userId", userId)
		ctx.Set("deptId", deptId)
		ctx.Next()
	}
}
